package com.functest.orm

import groovy.sql.Sql
import org.testng.annotations.DataProvider
import org.testng.annotations.Test

import java.text.SimpleDateFormat

import static com.functest.orm.TestData.*
import com.functest.framework.BaseFunctionalTest

/**
 * Created with IntelliJ IDEA.
 * User: KovalevAS
 * Date: 28.06.13
 * Time: 16:13
 * To change this template use File | Settings | File Templates.
 */
class SingleDbTableMapperTest extends BaseFunctionalTest {
    static {
        Class.forName('org.sqlite.JDBC');
    }

    @Test
    void fromDbFirstRowAsMapTest() {

        def date = new Date()
        def sdf = new SimpleDateFormat("MM/dd/yyyy")
        def today = sdf.format(date)

        def row = [id: 3, firstName: 'Sidor', lastName: 'Sidorov', today: today, status: StudentStatus.Student]
        asStep('validKeyField_ReturnsMap')
                {
                    assert com.functest.orm.TestData.student_table_full_mapper.fromDbFirstRowAsMap(3) == row
                }
        asStep('validField_ReturnsMap')
                {
                    assert com.functest.orm.TestData.student_table_full_mapper.fromDbFirstRowAsMap('Sidor', 'firstName') == row
                }
        asStep('invalidKeyField_ThrowingException')
                {
                    try {
                        com.functest.orm.TestData.student_table_full_mapper.fromDbFirstRowAsMap('1')
                        assert false, "NoSuchFieldError expected!"
                    }
                    catch (NoSuchFieldError ex) {
                        assert ex.message.contains('No data found for query')
                    }
                }
        asStep('invalidField_ThrowingException')
                {
                    try {
                        com.functest.orm.TestData.student_table_full_mapper.fromDbFirstRowAsMap('invalid_name', 'firstName')
                        assert false, "NoSuchFieldError expected!"
                    }
                    catch (NoSuchFieldError ex) {
                        assert ex.message.contains('No data found for query')
                    }
                }
    }




    final static Sql mapBackDb
    static {
        mapBackDb = Sql.newInstance('jdbc:sqlite::memory:', 'org.sqlite.SQLite')
        mapBackDb.with {
            execute("create table id_table (id int)")
            execute("insert into id_table values(42)")
        }
    }

    static class Id {
        int id
        int second
        int third
    }

    @DataProvider
    Object[][] mapBackData() {
        SingleDbTableMapper mapper = new SingleDbTableMapper(new MapperFields().with {
            field('id')
            field('second', 'id')
//            field('third', 'id')
            delegate as MapperFields
        },
                { SingleDbTableMapperTest.mapBackDb },
                'id_table',
                'id',
                Id
        )
        Map expectedMap = mapper.queryBuilder().allFields().build().executeRaw().first()
        Map columnAliases = mapper.queryBuilder().allFields().columnAliases
        Map transformedMap = mapper.transformMap(expectedMap, columnAliases)
//        assert columnAliases.size() == 2, "Not all fields has been aliased!"
        Id bean = mapper.buildFromTranformed(transformedMap, Id)

        return [[mapper, bean, columnAliases, expectedMap]]
    }

    @Test(dataProvider = 'mapBackData')
    void mapBackTest(SingleDbTableMapper mapper, Object bean, Map columnAliases, Map expectedMap) {
        asTest {
            asStep('mapBackTest') {
                Map mapBack = mapper.mapBack(bean, columnAliases)
                com.functest.framework.Assertions.weakAssertSilently('sizes does not matches', mapBack.size() == expectedMap.size())
                expectedMap.keySet().each { String fieldName ->
                    if (com.functest.framework.Assertions.weakAssertSilently("field $fieldName does not exists in result map", mapBack.keySet().contains(fieldName))) {
                        Object expectedValue = expectedMap.get(fieldName)
                        Object realValue = mapBack.get(fieldName)
                        com.functest.framework.Assertions.weakAssertSilently("\nvalues doses not matches" +
                                "\nfield: $fieldName" +
                                "\nexpected value: $expectedValue" +
                                "\nreal value: $realValue", expectedValue == realValue)
                    }
                }
            }
        }
    }
}
